package com.shanghaionstar.activity.webview.handler;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Build;
import android.os.Bundle;
import android.os.Message;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.GeolocationPermissions;
import android.webkit.JavascriptInterface;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.ProgressBar;

import com.onstar.cn.common.exception.OnStarException;
import com.onstar.cn.common.jsBridge.BridgeWebView;
import com.onstar.cn.common.jsBridge.BridgeWebViewClient;
import com.onstar.cn.common.log.LogManager;
import com.onstar.cn.common.util.CommonUtil;
import com.onstar.cn.common.util.Constants;
import com.onstar.cn.common.util.DeviceUtil;
import com.onstar.cn.framework.annotation.ContentView;
import com.onstar.cn.framework.annotation.FindViewById;
import com.onstar.cn.framework.mvp.base.core.BaseActivity;
import com.onstar.cn.framework.mvp.base.core.BasePresenter;
import com.onstar.cn.framework.mvp.base.core.PermissionCall;
import com.onstar.cn.mag.enumtype.CategoryType;
import com.onstar.cn.mag.enumtype.OSType;
import com.shanghaionstar.OnstarApplication;
import com.shanghaionstar.R;
import com.shanghaionstar.activity.LoadingActivity;
import com.shanghaionstar.activity.MainTabActivity;
import com.shanghaionstar.activity.WithActionSheetHelper;
import com.shanghaionstar.activity.iview.ICommonWebviewActivityView;
import com.shanghaionstar.enumtype.FunctionNameFindId;
import com.shanghaionstar.swipe.SwipeActivity;
import com.shanghaionstar.utils.AliPayByWebUtil;
import com.shanghaionstar.utils.ApplicationUtil;
import com.shanghaionstar.utils.BusinessUtil;
import com.shanghaionstar.utils.H5JSObject;
import com.shanghaionstar.weight.CommonNoDatasLayout;
import com.shanghaionstar.weight.TopLayout;

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by 7828wc on 2016/6/29.
 */
@ContentView(R.layout.onstar_common_webview)
public class CommonWebViewActivity extends SwipeActivity implements ICommonWebviewActivityView {
    @FindViewById
    private TopLayout top_layout;
    @FindViewById
    private BridgeWebView webview;
    @FindViewById
    private ProgressBar pb_loading;
    @FindViewById
    CommonNoDatasLayout cndl_noDatas;

    private Map<String, String> extraHeaders;
    private WebDataEntity entity;
    private IWebHandler handler;
    private boolean isError;
    private Bundle bundle;
    private WebBridgeHelper mBridgeHelper;

    @Override
    public BasePresenter getPresenter() {
        return null;
    }

    @SuppressLint("SetJavaScriptEnabled")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            WebView.enableSlowWholeDocumentDraw();
        }
        initData();
        initListener();
        initView();
    }

    public static void launchCommonWeb(Activity mActivity, Bundle bundle, WebDataEntity entity) {
        launchCommonWeb(mActivity, bundle, entity, null);
    }

    public static void launchCommonWebForResult(Activity mActivity, Bundle bundle, WebDataEntity entity, int requestCode) {
        Intent it = genLaunchIntent(mActivity, bundle, entity, null);
        mActivity.startActivityForResult(it, requestCode);
    }

    public static void launchCommonWeb(Activity mActivity, WebDataEntity entity) {
        launchCommonWeb(mActivity, null, entity);
    }

    public static void launchCommonWeb(Activity mActivity, Bundle bundle, WebDataEntity entity, Serializable serObj) {
        Intent it = genLaunchIntent(mActivity, bundle, entity, serObj);
        mActivity.startActivity(it);
    }

    @NonNull
    private static Intent genLaunchIntent(Activity mActivity, Bundle bundle, WebDataEntity entity, Serializable serObj) {
        Intent it = new Intent(mActivity, CommonWebViewActivity.class);
        if (bundle == null)
            bundle = new Bundle();
        if (entity != null) {
            bundle.putParcelable(IWebType.KEY_WEB_DATA, entity);
        }
        if (serObj != null)
            bundle.putSerializable(IWebType.KEY_SERIAL_DATA, serObj);
        it.putExtras(bundle);
        return it;
    }

    public static void launchCommonWeb(Activity mActivity, WebDataEntity entity, Serializable serObj) {
        launchCommonWeb(mActivity, null, entity, serObj);
    }


    private void initView() {
        String title = entity.getTopTitle();
        if (TextUtils.isEmpty(title) && TextUtils.isEmpty(top_layout.getTitle())) {
            top_layout.setVisibility(View.GONE);
        } else {
            top_layout.setTopTitle(title);
        }
        webview.setWebViewClient(new CustomWebViewClient(webview));
        setWebChromeClient();
//        if(handler instanceof DefaultWebHandler) {
//            ((DefaultWebHandler)handler).registerCommonHandler(webview);
//        }
    }

    public void registerH5Object(BridgeWebView webView, Context context) {
        H5JSObject jsObject = new H5JSObject(context);
        jsObject.setWebView(webView);
        webView.addJavascriptInterface(jsObject, "jsonObject");
    }

    private void setWebChromeClient() {
        webview.setWebChromeClient(new WebChromeClient() {
            @Override
            public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
//                result.confirm();
                return super.onJsAlert(view, url, message, result);
            }

            @Override
            public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
//                result.confirm();
                return super.onJsPrompt(view, url, message, defaultValue, result);
            }

            @Override
            public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
//                result.confirm();
                return super.onJsConfirm(view, url, message, result);
            }

            @Override
            public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
                callback.invoke(origin, true, false);
                super.onGeolocationPermissionsShowPrompt(origin, callback);
            }
        });
    }

    private void initListener() {
        setCloseListener();
        setBackClick();
    }

    private void initData() {
        bundle = getIntent().getExtras();
        entity = bundle.getParcelable(IWebType.KEY_WEB_DATA);
        setRequestParams(this);
        registerH5Object(webview, this);
        if (entity.what == IWebType.TYPE_NORMAL) {
            webview.loadUrl(entity.getLinkUrl(), extraHeaders);
//            webview.getSettings().setDomStorageEnabled(true);
        } else {
            if (entity.what == IWebType.TYPE_LOCATION) {
                requestRunTimePermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, new PermissionCall() {
                    @Override
                    public void requestSuccess() {
                        Message msg = Message.obtain();
                        msg.obj = entity;
                        msg.what = entity.what;
                        handler = getHandler(entity, CommonWebViewActivity.this);
                        handler.handMsg(msg);

                    }

                    @Override
                    public void refused() {

                    }
                });
            } else {
                Message msg = Message.obtain();
                msg.obj = entity;
                msg.what = entity.what;
                handler = getHandler(entity, CommonWebViewActivity.this);
                handler.handMsg(msg);
            }
        }

        mBridgeHelper = new WebBridgeHelper(CommonWebViewActivity.this);
        mBridgeHelper.registerCommonHandler(webview);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // don't hold on to the listener (which could potentially be an Activity)
//        mOnWebViewCreatedListener = null;
        // destroy the WebView completely
        if (webview != null) {
            // the WebView must be removed from the view hierarchy before calling destroy
            // to prevent a memory leak (#75)
            // See https://developer.android.com/reference/android/webkit/WebView.html#destroy%28%29
            ((ViewGroup) webview.getParent()).removeView(webview);
            webview.removeAllViews();
            webview.destroy();
            webview = null;
        }
    }


    private void setRequestParams(Context context) {
        extraHeaders = new HashMap<String, String>();
        extraHeaders.clear();
        extraHeaders.put("Content-Type", "application/json;charset=utf-8");
        extraHeaders.put("Accept-Language", "zh-CN");
        extraHeaders.put("Accept", "application/json");
        extraHeaders.put("Authorization", ApplicationUtil.getInstance().getToken());
//        平台_系统版本号_应用版本号_客户端语言_手机类型
        putClientInfo(context);
    }

    private void putClientInfo(Context context) {
        StringBuilder versionSB = new StringBuilder();
        DeviceUtil deviceUtil = new DeviceUtil(context);
        versionSB.append(OSType.ANDROID.value());
        versionSB.append("_");
        versionSB.append(deviceUtil.getAppVersion());
        versionSB.append("_");
        versionSB.append(deviceUtil.getAppVersionCode());
        versionSB.append("_");
        versionSB.append(DeviceUtil.getLanguage());
        versionSB.append("_");
        versionSB.append(DeviceUtil.getDeviceType());
        extraHeaders.put("CLIENT-INFO", versionSB.toString());
    }

    protected void setBackClick() {
        top_layout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                goBack();
            }
        });
    }

    @Override
    public void onBackPressed() {
        goBack();
    }

    protected void goBack() {
        if (!TextUtils.isEmpty(mBridgeHelper.getBackFunId())) {
            BusinessUtil.sendReportByClickType(OnstarApplication.getApplication(), mBridgeHelper.getBackFunId());
        }

        String url = webview.getUrl();
        if (!TextUtils.isEmpty(url) && url.contains("onstarCloseView=Yes")) {
            finish();
            return;
        }
        if (!TextUtils.isEmpty(url) && url.contains("onstarNativeBack=Yes")) {
            webview.callHandler("showDialog", "", null);
            return;
        }
        if (!CommonUtil.isNull(entity.getFromPage()) && entity.getFromPage().equals(LoadingActivity.class.getSimpleName())) {
            launchMain();
            return;
        }
        if (!TextUtils.isEmpty(url) && url.contains("onstarGoBack2=Yes")) {
            webview.goBack();
            webview.goBack();
            return;
        }
        if (!TextUtils.isEmpty(url) && url.contains("dealerList.html")) {
            BusinessUtil.sendReportByClickType(OnstarApplication.getApplication(), FunctionNameFindId.RecommendDealer_ClickBack.getStringValue());
            webview.goBack();
            return;
        }
        if (!TextUtils.isEmpty(url) && url.contains("http://m.amap.com/navi/")) {
            BusinessUtil.sendReportByClickType(OnstarApplication.getApplication(), FunctionNameFindId.DealerDetail_ClickBack.getStringValue());
            return;
        }
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//            webview.evaluateJavascript("javascript:document.getElementById('functionId').getAttribute('value')", new ValueCallback<String>() {
//                @Override
//                public void onReceiveValue(String value) {
//                    if (!TextUtils.isEmpty(value))
//                        BusinessUtil.sendReportByClickType(getApplication(), value);
//                }
//            });
//        }
        if (getString(R.string.user_operation_manual).equals(entity.getTopTitle()))
            finish();
        if (entity.isCanGoBack()) {
            if (webview.canGoBack()) {
                webview.goBack();
                top_layout.showClose(true);
            } else {
                finish();
            }
        } else {
            finish();
        }
    }

    @Override
    public void finish() {
        if (getString(R.string.h5_service_more).equalsIgnoreCase(entity.getTopTitle())) {
            BusinessUtil.sendReportByClickType(CommonWebViewActivity.this, FunctionNameFindId.More_Close.getStringValue());
        }
        if (getString(R.string.driver_assessment_title).equals(entity.getTopTitle())) {
            BusinessUtil.sendReportByClickType(this, FunctionNameFindId.CarAssmt_DiagnosticsReturn.getStringValue());
        }
        if (getString(R.string.verify_info3).equals(entity.getTopTitle())) {
            BusinessUtil.sendReportByClickType(this, FunctionNameFindId.LoginVerificationSuccess_ClickBack.getStringValue());
        }
        super.finish();
    }

    @Override
    public void setLoading(boolean isLoading) {
        pb_loading.setVisibility(isLoading ? ProgressBar.VISIBLE : ProgressBar.GONE);
    }

    @Override
    public void onResponseError(OnStarException e) {

    }

    @Override
    public void onReponseSuccess(Object object) {
        Message msg = Message.obtain();
        msg.obj = object;
        msg.what = IWebType.TYPE_CONTENT_DETAIL;
        if (handler != null)
            handler.handMsg(msg);
    }

    @Override
    public Activity onActivity() {
        return this;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(helper != null)
             helper.onActivityResult(requestCode, resultCode, data);
        handleOnResult(requestCode, resultCode, data);
    }

    private void handleOnResult(int requestCode, int resultCode, Intent data) {
        Message msg = Message.obtain();
        msg.what = IWebType.TYPE_ON_ACTIVITY_RESULT;
        msg.arg1 = requestCode;
        msg.arg2 = resultCode;
        msg.obj = data;
        if (handler != null)
            handler.handMsg(msg);
    }


    private class CustomWebViewClient extends BridgeWebViewClient {
        public CustomWebViewClient(BridgeWebView webView) {
            super(webView);
        }


        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.getSettings().setBlockNetworkImage(false);
            handleDiffMsg(IWebType.TYPE_ON_OVERRIDE_URL, url);
            if (!url.contains("shanghaionstar")) {
                if (Build.VERSION.SDK_INT >= 21) {
                    view.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
                }
            }
            if (url.contains("tel:")) {
                Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
                startActivity(intent);
            }

            if (url.startsWith("alipays:") || url.startsWith("alipay")) {
                try {
                    startActivity(new Intent("android.intent.action.VIEW", Uri.parse(url)));
                } catch (Exception e) {
                    new AlertDialog.Builder(CommonWebViewActivity.this)
                            .setMessage("未检测到支付宝客户端，请安装后重试。")
                            .setPositiveButton("立即安装", new DialogInterface.OnClickListener() {

                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    Uri alipayUrl = Uri.parse("https://d.alipay.com");
                                    startActivity(new Intent("android.intent.action.VIEW", alipayUrl));
                                }
                            }).setNegativeButton("取消", null).show();
                }
                return true;
            }
//
            boolean isPay = new AliPayByWebUtil(CommonWebViewActivity.this, webview).pay(url);
            if (isPay) {
                return isPay;
            }

//            if (!(url.startsWith("http") || url.startsWith("https"))) {
//                return true;
//            }
//            view.loadUrl(url);
            return super.shouldOverrideUrlLoading(view, url);
        }


        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
//            handler.proceed();
            super.onReceivedSslError(view, handler, error);
            webview.loadUrl(entity.getLinkUrl(), extraHeaders);
        }

        @SuppressWarnings("deprecation")
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            isError = false;
            pb_loading.setVisibility(ProgressBar.VISIBLE);
            top_layout.showRightButton(false);
            handleDiffMsg(IWebType.TYPE_ON_PAGE_STARTED, url);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
//            top_layout.showRightButton(false);
            if (isError) {
                webview.setVisibility(View.GONE);
            } else {
                webview.setVisibility(WebView.VISIBLE);
                cndl_noDatas.setVisibility(View.GONE);
            }
            pb_loading.setVisibility(ProgressBar.GONE);

            CategoryType categoryType = bundle == null ? null : (CategoryType) bundle.getSerializable("categoryType");
            if (!CommonUtil.isNull(view.getTitle())  && TextUtils.isEmpty(entity.getTopTitle()) && categoryType == null) {
                top_layout.setVisibility(View.VISIBLE);
                top_layout.setTopTitle(view.getTitle());
            }
            handleDiffMsg(IWebType.TYPE_ON_PAGE_FINISHED, url);
        }

        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            super.onReceivedError(view, errorCode, description, failingUrl);
            isError = true;
            webview.setVisibility(View.GONE);
            showEmptyView(View.VISIBLE, R.string.no_set_meal_data, R.drawable.common_refresh_data);
            cndl_noDatas.setOnRefreshListener((new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    webview.loadUrl(entity.getLinkUrl(), extraHeaders);
                    entity.setCanGoBack(false);
                }

            }));
        }

        @Override
        public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
            super.onReceivedHttpError(view, request, errorResponse);
        }
    }


    private void handleDiffMsg(int type, String url) {
        if (handler == null)
            return;
        Message msg = Message.obtain();
        msg.what = type;
        msg.obj = url;
        handler.handMsg(msg);
    }

    public void showEmptyView(int visible, int tipId, int imgId) {
        cndl_noDatas.setVisibility(visible);
        cndl_noDatas.setHintText(tipId);
        cndl_noDatas.setRefreshImage(imgId);
        cndl_noDatas.showIcon(true);
    }

    public BridgeWebView getWebview() {
        return webview;
    }

    public void setWebview(BridgeWebView webview) {
        this.webview = webview;
    }

    public TopLayout getTop_layout() {
        return top_layout;
    }

    public void setTop_layout(TopLayout top_layout) {
        this.top_layout = top_layout;
    }

    public Bundle getBundle() {
        return bundle;
    }

    public void setBundle(Bundle bundle) {
        this.bundle = bundle;
    }

    public Map<String, String> getExtraHeaders() {
        return extraHeaders;
    }

    public void setExtraHeaders(Map<String, String> extraHeaders) {
        this.extraHeaders = extraHeaders;
    }

    public IWebHandler getHandler(WebDataEntity entity, Context context) {
        try {
            Class<?> clazz = Class.forName(entity.getClzName());
            Constructor c1 = clazz.getDeclaredConstructor(Context.class);
            c1.setAccessible(true);
            IWebHandler handler = (IWebHandler) c1.newInstance(context);
            return handler;
        } catch (ClassNotFoundException e) {
            LogManager.getInstance().e(e.getMessage());
        } catch (InstantiationException e) {
            LogManager.getInstance().e(e.getMessage());
        } catch (InvocationTargetException e) {
            LogManager.getInstance().e(e.getMessage());
        } catch (NoSuchMethodException e) {
            LogManager.getInstance().e(e.getMessage());
        } catch (IllegalAccessException e) {
            LogManager.getInstance().e(e.getMessage());
        } catch (Exception e) {
            LogManager.getInstance().e(e.getMessage());
        }
        return null;
    }


    private void setCloseListener() {
        top_layout.setCloseSetListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }


    private void launchMain() {
        Intent it = new Intent(CommonWebViewActivity.this, MainTabActivity.class);
        it.putExtra("receiveType", bundle.getString("receiveType"));
        it.putExtra("uri", bundle.getString("uri"));
        it.putExtra("title", bundle.getString("title"));
        it.putExtra(Constants.PARTNER_AUTONAV_FLAG, bundle.getBoolean(Constants.PARTNER_AUTONAV_FLAG));
        it.putExtra(Constants.PARTNER_3RD_FLAG, bundle.getString(Constants.PARTNER_3RD_FLAG));
        Bundle bundle = new Bundle();
        bundle.putSerializable(Constants.PARTNER_3RD_POI, bundle.getSerializable(Constants.PARTNER_3RD_POI));
        it.putExtras(bundle);
        startActivity(it);
        finish();
    }

    private WithActionSheetHelper helper;

    @JavascriptInterface
    public void openCamera(BaseActivity mActivity) {
        helper = new WithActionSheetHelper(mActivity);
        helper.showDialogToTakeChoosePicture();
    }


}

